home *** CD-ROM | disk | FTP | other *** search
/ Revolution - Das Atari CD Magazin 1997 / Revolution - Das Atari CD Magazin 1.iso / software / anwendng / qed_397 / sourcen / block.c < prev    next >
C/C++ Source or Header  |  1996-12-29  |  16KB  |  814 lines

  1. #include "global.h"
  2. #include "clipbrd.h"
  3. #include "edit.h"
  4. #include "obj.h"
  5. #include "rsc.h"
  6. #include "set.h"
  7. #include "trash.h"
  8. #include "block.h"
  9.  
  10.  
  11. /* lokale Prototypen *******************************************************/
  12. LOCAL VOID        block_demark    (TEXTP t_ptr);
  13. LOCAL BOOLEAN    tab_ok            (LINEP a, BOOLEAN tab, WORD tabsize);
  14. LOCAL VOID        block_setzen    (TEXTP t_ptr);
  15. LOCAL BOOLEAN    block_delete    (TEXTP t_ptr, RINGPTR t);
  16. LOCAL BOOLEAN    block_einsetzen(TEXTP t_ptr, RINGPTR t);
  17.  
  18. /* lokale Variablen ********************************************************/
  19.  
  20. LOCAL WORD    undo_anf_x, undo_end_x;
  21. LOCAL LONG    undo_anf_y, undo_end_y;
  22.  
  23.  
  24. VOID blk_mark_all(TEXTP t_ptr)
  25. {
  26.     LINEP col;
  27.  
  28.     if (t_ptr->block)
  29.         block_demark(t_ptr);
  30.     col = FIRST(&t_ptr->text);
  31.     t_ptr->x1 = 0;
  32.     t_ptr->p1 = col;
  33.     t_ptr->z1 = 0;
  34.     col = LAST(&t_ptr->text);
  35.     t_ptr->x2 = col->len;
  36.     t_ptr->p2 = col;
  37.     t_ptr->z2 = t_ptr->text.lines-1;
  38.     t_ptr->block_dir = FALSE;            /* Anfang und Ende nicht vertauscht */
  39.     block_setzen(t_ptr);
  40.     make_chg(t_ptr->link,BLK_CHANGE,0);
  41.     make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
  42. }
  43.  
  44.  
  45. VOID blk_mark_word(TEXTP t_ptr)        /* Wort unter dem Cursor markieren */
  46. {
  47.     WORD    pos,len;
  48.     UBYTE    *str;
  49.  
  50.     pos = t_ptr->xpos;
  51.     str = TEXT(t_ptr->cursor_line)+pos;
  52.     len = t_ptr->cursor_line->len;
  53.     while(pos>=0 && setin(t_ptr->loc_opt->wort_set,*str))
  54.     {
  55.         pos--;
  56.         str--;
  57.     }
  58.     str++; pos++;
  59.     t_ptr->xpos = pos;
  60.     blk_mark(t_ptr, 0);
  61.     while(pos<=len && setin(t_ptr->loc_opt->wort_set,*str))
  62.     {
  63.         pos++;
  64.         str++;
  65.     }
  66.     t_ptr->xpos = pos;
  67.     blk_mark(t_ptr, 1);
  68.     restore_edit();
  69. }
  70.  
  71.  
  72. VOID get_blk_mark(TEXTP t_ptr, LONG *y, WORD *x)
  73. {
  74.     if (t_ptr->block_dir)
  75.     {
  76.         *y = t_ptr->z2;
  77.         *x = t_ptr->x2;
  78.     }
  79.     else
  80.     {
  81.         *y = t_ptr->z1;
  82.         *x = t_ptr->x1;
  83.     }
  84. }
  85.  
  86. VOID blk_mark(TEXTP t_ptr, WORD marke)
  87. /* Blockstart und -ende setzen    */
  88. /* marke : 0 und 1                    */
  89. {
  90.     if (marke==0)    /* Anfang setzten */
  91.     {
  92.         blk_demark(t_ptr);
  93.         t_ptr->p2 = t_ptr->p1 = t_ptr->cursor_line;
  94.         t_ptr->z2 = t_ptr->z1 = t_ptr->ypos;
  95.         t_ptr->x2 = t_ptr->x1 = t_ptr->xpos;
  96.         t_ptr->block_dir = FALSE;
  97.     }
  98.     else                /* Block aufziehen */
  99.     {
  100.         if (t_ptr->block_dir)
  101.         {
  102.             if (t_ptr->p1 == t_ptr->cursor_line && t_ptr->x1 == t_ptr->xpos)
  103.                 return;                                /* Keine Änderung */
  104.             if (t_ptr->block)
  105.             {
  106.                 block_demark(t_ptr);
  107.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
  108.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
  109.             }
  110.             else
  111.             {
  112.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
  113.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
  114.             }
  115.             t_ptr->p1 = t_ptr->cursor_line;
  116.             t_ptr->x1 = t_ptr->xpos;
  117.             t_ptr->z1 = t_ptr->ypos;
  118.         }
  119.         else
  120.         {
  121.             if (t_ptr->p2==t_ptr->cursor_line && t_ptr->x2==t_ptr->xpos)
  122.                 return;                                /* Keine Änderung */
  123.             if (t_ptr->block)
  124.             {
  125.                 block_demark(t_ptr);
  126.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
  127.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
  128.             }
  129.             else
  130.             {
  131.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
  132.                 make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
  133.             }
  134.             t_ptr->p2 = t_ptr->cursor_line;
  135.             t_ptr->x2 = t_ptr->xpos;
  136.             t_ptr->z2 = t_ptr->ypos;
  137.         }
  138.         block_setzen(t_ptr);
  139.     }
  140. }
  141.  
  142.  
  143. VOID blk_demark(TEXTP t_ptr)
  144. {
  145.     if (t_ptr->block)
  146.     {
  147.         block_demark(t_ptr);
  148.         make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
  149.         make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
  150.         t_ptr->p1 = t_ptr->p2 = NULL;
  151.         t_ptr->z1 = t_ptr->z2 = -1;
  152.     }
  153. }
  154.  
  155.  
  156. VOID blk_copy(TEXTP t_ptr, BOOLEAN add)
  157. /* Kopiert Block aus einem Text auf das Clipbrd */
  158. {
  159.     RING t;
  160.  
  161.     if (!t_ptr->block)
  162.         return;
  163.     if (!ist_mem_frei())
  164.         return;
  165.     block_copy(t_ptr,&t);
  166.     if (add)
  167.         clip_add_text(&t);
  168.     else
  169.         clip_takes_text(&t);
  170. }
  171.  
  172. VOID line_copy(TEXTP t_ptr, BOOLEAN add)
  173. /* Kopiert aktuelle Zeile auf das Clipboard */
  174. {
  175.     LINEP    col = t_ptr->cursor_line;
  176.     WORD    old_x;
  177.  
  178.     old_x = t_ptr->xpos;
  179.     t_ptr->xpos = 0;
  180.     blk_mark(t_ptr,0);
  181.     if (IS_LAST(col))
  182.     {
  183.         t_ptr->xpos = col->len;
  184.         blk_mark(t_ptr,1);
  185.         t_ptr->xpos = old_x;
  186.     }
  187.     else
  188.     {
  189.         NEXT(col);
  190.         t_ptr->cursor_line = col;
  191.         blk_mark(t_ptr,1);
  192.         VORG(col);
  193.         t_ptr->cursor_line = col;
  194.         t_ptr->xpos = old_x;
  195.     }
  196.     blk_copy(t_ptr,add);
  197.     blk_demark(t_ptr);
  198. }
  199.  
  200. VOID blk_paste(TEXTP t_ptr, RINGP t)
  201. /* Setzt den Text t im Text an Cursorposition ein */
  202. /* Der Cursor steht anschließend dahinter */
  203. /* Ist ein Block da, wird er gelöscht */
  204. {
  205.     if (!ist_mem_frei())
  206.         return;
  207.     blk_delete(t_ptr);
  208.     block_einsetzen(t_ptr, t);
  209.     t_ptr->moved++;
  210.     add_undo(BLK_PASTE);
  211. }
  212.  
  213. VOID blk_delete(TEXTP t_ptr)
  214. {
  215.     RING t;
  216.  
  217.     if(!t_ptr->block)
  218.         return;
  219.     if (!ist_mem_frei())
  220.         return;
  221.     if (!block_delete(t_ptr, &t))
  222.         return;
  223.     trash_takes_text(&t);
  224.     t_ptr->moved++;
  225.     add_undo(BLK_DEL);
  226. }
  227.  
  228. VOID blk_cut(TEXTP t_ptr, BOOLEAN add)
  229. {
  230.     RING t, t2;
  231.  
  232.     if (!t_ptr->block)
  233.         return;
  234.     if (!ist_mem_frei())
  235.         return;
  236.     if (!block_delete(t_ptr, &t))
  237.         return;
  238.     init_textring(&t2);
  239.     if (doppeln(&t,&t2))
  240.     {
  241.         if (add)
  242.             clip_add_text(&t2);
  243.         else
  244.             clip_takes_text(&t2);
  245.     }
  246.     undo_takes_text(&t);
  247.     t_ptr->moved++;
  248.     add_undo(BLK_CUT);
  249. }
  250.  
  251. VOID blk_undo(TEXTP t_ptr, WORD undo)
  252. {
  253.     RING    t;
  254.  
  255.     if (!ist_mem_frei())
  256.         return;
  257.     if (undo==BLK_PASTE || undo==BLK_PASTE_TRASH)
  258.     /* Block muß wieder gelöscht werden */
  259.     {
  260.         blk_demark(t_ptr);
  261.         t_ptr->p1 = get_line(&t_ptr->text,undo_anf_y);
  262.         t_ptr->z1 = undo_anf_y;
  263.         t_ptr->x1 = undo_anf_x;
  264.         t_ptr->p2 = get_line(&t_ptr->text,undo_end_y);
  265.         t_ptr->z2 = undo_end_y;
  266.         t_ptr->x2 = undo_end_x;
  267.         block_setzen(t_ptr);
  268.         block_delete(t_ptr, &t);                /* Block ausschneiden und als Undotext */
  269.         if (undo==BLK_PASTE)
  270.         {
  271.             undo_takes_text(&t);
  272.             add_undo(BLK_CUT);
  273.         }
  274.         else
  275.         {
  276.             trash_takes_text(&t);
  277.             add_undo(BLK_DEL);
  278.         }
  279.         t_ptr->moved++;
  280.     }
  281.     if (undo==BLK_CUT)                            /* Block muß wieder eingefügt werden */
  282.     {
  283.         RINGP tp;
  284.  
  285.         t_ptr->xpos = undo_anf_x;
  286.         tp = get_undo_text();
  287.         block_einsetzen(t_ptr, tp);
  288.         add_undo(BLK_PASTE);
  289.     }
  290.     if (undo==BLK_DEL)                            /* Text aus Papierkorb wieder einsetzten */
  291.     {
  292.         RINGP tp;
  293.  
  294.         t_ptr->xpos = undo_anf_x;
  295.         tp = &(get_text(itrash)->text);
  296.         block_einsetzen(t_ptr, tp);
  297.         add_undo(BLK_PASTE_TRASH);
  298.     }
  299. }
  300.  
  301. VOID blk_right(TEXTP t_ptr, BOOLEAN onechar)
  302. {
  303.     LINEP     lauf;
  304.     LONG        y, ende;
  305.     BOOLEAN    t = t_ptr->loc_opt->tab;
  306.  
  307.     if (!t_ptr->block)
  308.         return;
  309.     lauf = t_ptr->p1;
  310.     y = t_ptr->z1;
  311.     ende = t_ptr->z2;
  312.     if (y < ende)
  313.     {
  314.         WORD  anz, i;
  315.         UBYTE    c, *str;
  316.  
  317.         if (t)
  318.         {
  319.             anz = 1;
  320.             c = '\t';
  321.         }
  322.         else
  323.         {
  324.             anz = t_ptr->loc_opt->tabsize;
  325.             c = ' ';
  326.         }
  327.         if (onechar)
  328.         {
  329.             anz = 1;
  330.             c = ' ';
  331.         }
  332.         t_ptr->moved++;
  333.         clr_undo();
  334.         if (t_ptr->x1>0) t_ptr->x1 += anz;
  335.         while (y<ende || t_ptr->x2>0)
  336.         {
  337.             if (lauf->len+anz>MAX_LINE_LEN)
  338.             {
  339.                 inote(1, TOOLONG, MAX_LINE_LEN);
  340.                 break;
  341.             }
  342.             str = REALLOC(&lauf,0,anz);
  343.             for (i=anz; (--i)>=0; )
  344.                 *str++ = c;
  345.             if (y==t_ptr->z1)
  346.                 t_ptr->p1 = lauf;
  347.             if (y==ende)
  348.             {
  349.                 t_ptr->p2 = lauf;
  350.                 break;
  351.             }
  352.             NEXT(lauf);
  353.             y++;
  354.         }
  355.         if (t_ptr->x2>0) t_ptr->x2 += anz;
  356.         t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
  357.         make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->z1);
  358.     }
  359. }
  360.  
  361. VOID blk_left(TEXTP t_ptr, BOOLEAN onechar)
  362. {
  363.     LINEP     lauf;
  364.     LONG        y, ende;
  365.     BOOLEAN    t = t_ptr->loc_opt->tab;
  366.     WORD        ts = t_ptr->loc_opt->tabsize;
  367.  
  368.     if (!t_ptr->block)
  369.         return;
  370.     if (!ist_mem_frei())
  371.         return;
  372.     lauf = t_ptr->p1;
  373.     y = t_ptr->z1;
  374.     ende = t_ptr->z2;
  375.     if (y < ende)
  376.     {
  377.         WORD anz;
  378.  
  379.         if (t)
  380.             anz = 1;
  381.         else
  382.             anz = ts;
  383. /*
  384.    Rene, kommt noch!
  385. if (onechar)
  386. {
  387. anz = ts = 1;
  388. t = FALSE;
  389. }
  390. */
  391.         t_ptr->moved++;
  392.         clr_undo();
  393.         if (tab_ok(lauf,t,ts))
  394.         {
  395.             if (t_ptr->x1 <= anz)
  396.                 t_ptr->x1 = 0;
  397.             else
  398.                 t_ptr->x1 -= anz;
  399.         }
  400.         while (y < ende || t_ptr->x2 > 0)
  401.         {
  402.             if (tab_ok(lauf,t,ts))
  403.             {
  404.                 REALLOC(&lauf, 0, -anz);
  405.                 if (y == t_ptr->z1)
  406.                     t_ptr->p1 = lauf;
  407.                 if (y == ende)
  408.                     t_ptr->p2 = lauf;
  409.             }
  410.             if (y == ende)
  411.                 break;
  412.             NEXT(lauf);
  413.             y++;
  414.         }
  415.         if (tab_ok(lauf,t,ts))
  416.         {
  417.             if (t_ptr->x2 <= anz)
  418.                 t_ptr->x2 = 0;
  419.             else
  420.                 t_ptr->x2 -= anz;
  421.         }
  422.         t_ptr->cursor_line = get_line(&t_ptr->text, t_ptr->ypos);
  423.         make_chg(t_ptr->link, POS_CHANGE, 0);
  424.         make_chg(t_ptr->link, TOTAL_CHANGE, t_ptr->z1);
  425.     }
  426. }
  427.  
  428. /*-------------------------------------------------------------------*/
  429.  
  430. VOID str_ch_uprlwr (UBYTE *line)
  431. {
  432.     UBYTE stra[2],strb[2];
  433.  
  434.     stra[1] = strb[1] = EOS;
  435.  
  436.     while (*line != EOS)
  437.     {
  438.         stra[0] = *line;
  439.         strb[0] = *line;
  440.         str_upper(stra);
  441.         str_lower(strb);
  442.         if (stra[0] == *line)
  443.             *line = strb[0];
  444.         else
  445.             *line = stra[0];
  446.  
  447.         line++;
  448.     }
  449. }
  450.  
  451. VOID strcap (UBYTE *line, SET wort_set)
  452. {
  453.     UBYTE stra[2],strb[2];
  454.  
  455.     stra[1] = strb[1] = EOS;
  456.     stra[0] = *line;
  457.     if (setin(wort_set,stra[0]))
  458.     {
  459.         str_upper(stra);
  460.         *line=stra[0];
  461.     }
  462.     line++;
  463.     while (*line != EOS)
  464.     {
  465.         strb[0] = *(line-1);
  466.         if (!setin(wort_set,strb[0]))
  467.         {
  468.             stra[0] = *line;
  469.             if (setin(wort_set,stra[0]))
  470.             {
  471.                 str_upper(stra);
  472.                 *line=stra[0];
  473.             }
  474.         }
  475.         line++;
  476.     }
  477. }
  478.  
  479. VOID blk_upplow(TEXTP t_ptr, int type)
  480. {
  481.     LINEP    lauf;
  482.     LONG    y, ende;
  483.  
  484.     if (!t_ptr->block)
  485.         return;
  486.  
  487.     lauf = t_ptr->p1;
  488.     y = t_ptr->z1;
  489.     ende = t_ptr->z2;
  490.     if (y <= ende)
  491.     {
  492.         UBYTE *Tline, c;
  493.  
  494.         t_ptr->moved++;
  495.         clr_undo();
  496.         while (y < ende || t_ptr->x2 > 0)
  497.         {
  498.             if (y == t_ptr->z1)
  499.                 Tline = TEXT(lauf)+t_ptr->x1;
  500.             else
  501.                 Tline = TEXT(lauf);
  502.             if (y == ende)
  503.             {
  504.                 c = *(TEXT(lauf)+t_ptr->x2);
  505.                 *(TEXT(lauf)+t_ptr->x2) = EOS; /* Zeile unterbrechen */
  506.             }
  507.             switch (type)
  508.             {
  509.                 case BLK_UPPER:
  510.                     str_upper (Tline);
  511.                     break;
  512.                 case BLK_LOWER :
  513.                     str_lower (Tline);
  514.                     break;
  515.                 case BLK_CH_UPLO :
  516.                     str_ch_uprlwr (Tline);
  517.                     break;
  518.                 case BLK_CAPS :
  519.                     str_lower (Tline);
  520.                     strcap (Tline,t_ptr->loc_opt->wort_set);
  521.                     break;
  522.             }
  523.             if (y == ende)
  524.             {
  525.                 *(TEXT(lauf)+t_ptr->x2) = c; /* Zeile restaurieren */
  526.                 break;
  527.             }
  528.             NEXT(lauf);
  529.             y++;
  530.         }
  531.         t_ptr->moved++;
  532.         make_chg(t_ptr->link, POS_CHANGE, 0);
  533.         make_chg(t_ptr->link, TOTAL_CHANGE, t_ptr->z1);
  534.     }
  535. }
  536.  
  537. /*----------------------------------------------------------------*/
  538.  
  539. LOCAL VOID block_demark(TEXTP t_ptr)
  540. {
  541.     t_ptr->block = FALSE;
  542.     t_ptr->cursor = TRUE;
  543. }
  544.  
  545. LOCAL BOOLEAN tab_ok(LINEP a, BOOLEAN tab, WORD tabsize)
  546. {
  547.     WORD     anz;
  548.     UBYTE *str;
  549.  
  550.     if (tab)
  551.     {
  552.         if (a->len==0) return(FALSE);
  553.         str = TEXT(a);
  554.         if (*str!='\t') return(FALSE);
  555.     }
  556.     else
  557.     {
  558.         anz = tabsize;
  559.         if (a->len<anz) return(FALSE);
  560.         str = TEXT(a);
  561.         while ((--anz)>=0)
  562.         {
  563.             if (*str++!=' ') return(FALSE);
  564.         }
  565.     }
  566.     return(TRUE);
  567. }
  568.  
  569. LOCAL VOID block_setzen(TEXTP t_ptr)
  570. {
  571.     if (t_ptr->p1 == t_ptr->p2 && t_ptr->x1 == t_ptr->x2)
  572.         return;
  573.  
  574.     if (t_ptr->z1 > t_ptr->z2)            /* Richtung falsch => tauschen */
  575.     {
  576.         LINEP col;
  577.         LONG    l;
  578.         WORD    i;
  579.  
  580.         t_ptr->block_dir ^= TRUE;
  581.         i = t_ptr->x1;
  582.         t_ptr->x1 = t_ptr->x2;
  583.         t_ptr->x2 = i;
  584.         col = t_ptr->p1;
  585.         t_ptr->p1 = t_ptr->p2;
  586.         t_ptr->p2 = col;
  587.         l = t_ptr->z1;
  588.         t_ptr->z1 = t_ptr->z2;
  589.         t_ptr->z2 = l;
  590.     }
  591.     else if (t_ptr->z1 == t_ptr->z2 && t_ptr->x1 > t_ptr->x2)
  592.     {
  593.         WORD xw;
  594.  
  595.         t_ptr->block_dir ^= TRUE;
  596.         xw = t_ptr->x1;
  597.         t_ptr->x1 = t_ptr->x2;
  598.         t_ptr->x2 = xw;
  599.     }
  600.     t_ptr->block = TRUE;
  601.     t_ptr->cursor = FALSE;
  602. }
  603.  
  604. LOCAL BOOLEAN block_delete(TEXTP t_ptr, RINGP t)
  605. {
  606.     LINEP b_anf_col, b_end_col;
  607.     LONG    lines;
  608.  
  609.     b_anf_col = t_ptr->p1;
  610.     b_end_col = t_ptr->p2;
  611.     if (b_end_col->len-t_ptr->x2+t_ptr->x1>MAX_LINE_LEN)
  612.     {
  613.         inote(1, TOOLONG, MAX_LINE_LEN);
  614.         return(FALSE);
  615.     }
  616.  
  617.     /* Cursor an den Blockanfang bringen */
  618.     t_ptr->ypos = t_ptr->z1;
  619.     t_ptr->xpos = t_ptr->x1;
  620.  
  621.     undo_anf_y = t_ptr->z1;
  622.     undo_anf_x = t_ptr->x1;
  623.     undo_y = t_ptr->ypos;                /* globale Merkvariable */
  624.  
  625.     lines = t_ptr->z2-t_ptr->z1+1;
  626.     if (lines==1)                            /* ganz ohne Zeilenumbruch */
  627.     {
  628.         WORD len = t_ptr->x2-t_ptr->x1;
  629.         LINEP    b;
  630.  
  631.         init_textring(t);
  632.         b = FIRST(t);
  633.         INSERT(&b, 0, len, TEXT(b_anf_col)+t_ptr->x1);
  634.         REALLOC(&b_anf_col, t_ptr->x1, -len);
  635.         t_ptr->cursor_line = b_anf_col;
  636.     }
  637.     else
  638.     {
  639.         col_split(&b_end_col,t_ptr->x2);
  640.         NEXT(b_end_col);
  641.         col_split(&b_anf_col,t_ptr->x1);
  642.  
  643.         /* Block ausschneiden */
  644.         FIRST(t) = b_anf_col->nachf;
  645.         b_anf_col->nachf->vorg = &t->head;
  646.         LAST(t) = b_end_col->vorg;
  647.         b_end_col->vorg->nachf = &t->tail;
  648.         t->lines = lines;
  649.  
  650.         /* Kette wieder schließen */
  651.         b_anf_col->nachf = b_end_col;
  652.         b_end_col->vorg = b_anf_col;
  653.         col_concate(&b_anf_col);
  654.         t_ptr->cursor_line = b_anf_col;
  655.     }
  656.     if (lines==1)
  657.     {
  658.         make_chg(t_ptr->link,POS_CHANGE, 0);
  659.         make_chg(t_ptr->link,LINE_CHANGE, undo_y);
  660.     }
  661.     else if (lines==2)
  662.     {
  663.         make_chg(t_ptr->link,POS_CHANGE, 0);
  664.         make_chg(t_ptr->link,LINE_CHANGE, undo_y);
  665.         make_chg(t_ptr->link,SCROLL_UP, undo_y+1);
  666.     }
  667.     else
  668.     {
  669.         make_chg(t_ptr->link,POS_CHANGE, 0);
  670.         make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->z1);
  671.     }
  672.     t_ptr->block = FALSE;
  673.     t_ptr->cursor = TRUE;
  674.     t_ptr->text.lines -= (lines-1);
  675.  
  676.     return(TRUE);
  677. }
  678.  
  679. VOID block_copy(TEXTP t_ptr, RINGP t)
  680. {
  681.     LINEP a, lauf;
  682.  
  683.     init_textring(t);
  684.     a = FIRST(t);                                    /* erste Zeile */
  685.     lauf = t_ptr->p1;                                /* Blockstart */
  686.     if (lauf==t_ptr->p2)                            /* nur eine Zeile */
  687.     {
  688.         INSERT(&a, 0, t_ptr->x2-t_ptr->x1, TEXT(lauf)+t_ptr->x1);
  689.         a->info |= ABSATZ;
  690.     }
  691.     else
  692.     {
  693.         LINEP new, ende;
  694.  
  695.         /* erste Zeile teilweise */
  696.         INSERT(&a, 0, lauf->len-t_ptr->x1, TEXT(lauf)+t_ptr->x1);
  697.         if (lauf->info&ABSATZ) a->info |= ABSATZ;
  698.         else a->info &= (~ABSATZ);
  699.         ende = t_ptr->p2;
  700.         NEXT(lauf);
  701.         NEXT(a);                                                    /* TAIL im neuen Text */
  702.         while (lauf!=ende && ist_mem_frei())
  703.         {
  704.             new = new_col_w(TEXT(lauf), lauf->len);
  705.             if (lauf->info&ABSATZ) new->info |= ABSATZ;
  706.             col_insert(a->vorg,new);
  707.             t->lines++;
  708.             NEXT(lauf);
  709.         }
  710.         new = new_col_w(TEXT(lauf),t_ptr->x2);            /* letzte Zeile teilweise */
  711.         new->info |= ABSATZ;
  712.         col_insert(a->vorg,new);
  713.         t->lines++;
  714.     }
  715. }
  716.  
  717. /* Der Cursor von t_ptr steht anschließend hinter der Einfügung */
  718. LOCAL BOOLEAN block_einsetzen(TEXTP t_ptr, RINGP in)
  719. {
  720.     RING    t;
  721.     LINEP    a,b,
  722.             col = t_ptr->cursor_line;
  723.     LONG    len;
  724.  
  725.     a = FIRST(in);
  726.     b = LAST(in);
  727.     if ((a!=b &&
  728.           (t_ptr->xpos+a->len>MAX_LINE_LEN ||
  729.             b->len+(col->len-t_ptr->xpos)>MAX_LINE_LEN)) ||
  730.          (a==b &&
  731.           col->len+a->len>MAX_LINE_LEN))
  732.     {
  733.         inote(1, TOOLONG, MAX_LINE_LEN);
  734.         return(FALSE);
  735.     }
  736.  
  737.     init_textring(&t);
  738.     doppeln(in, &t);
  739.     a = FIRST(&t);
  740.     b = LAST(&t);
  741.  
  742.     if (t.lines==1)            /* Ganz ohne Zeilenveränderung */
  743.         make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
  744.     else if(t.lines==2)        /* Einen Zeilenumbruch */
  745.     {
  746.         make_chg(t_ptr->link,SCROLL_DOWN,t_ptr->ypos+1);
  747.         make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
  748.         make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos+1);
  749.     }
  750.     else
  751.     {
  752.         make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->ypos);
  753.     }
  754.  
  755.     len = t.lines-1;
  756.     t_ptr->text.lines += len;
  757.  
  758.     undo_anf_y = t_ptr->ypos;
  759.     undo_anf_x = t_ptr->xpos;
  760.     undo_end_y = undo_anf_y+len;
  761.     undo_end_x = b->len;
  762.     undo_y = t_ptr->ypos;                                /* globale Merkvariable */
  763.     if (len==0)
  764.     {
  765.         INSERT(&col, t_ptr->xpos, a->len, TEXT(a));
  766.         undo_end_x += t_ptr->xpos;
  767.         kill_textring(&t);
  768.     }
  769.     else
  770.     {
  771.         col_split(&col,t_ptr->xpos);                    /* Textzeile splitten   */
  772.  
  773.         col->nachf->vorg = b;                            /* Block einfügen unten */
  774.         b->nachf = col->nachf;
  775.         col_concate(&b);                                    /* Untere letzte Zeile    */
  776.  
  777.         col->nachf = a;                                    /* Block einfügen oben */
  778.         a->vorg = col;
  779.         col_concate(&col);
  780.     }
  781.     /* Cursor hinter Einfügung */
  782.     t_ptr->cursor_line = get_line(&t_ptr->text,undo_end_y);
  783.     t_ptr->ypos = undo_end_y;
  784.     t_ptr->xpos = undo_end_x;
  785.     t_ptr->moved++;
  786.     make_chg(t_ptr->link, POS_CHANGE, 0);
  787.     return(TRUE);
  788. }
  789.  
  790. VOID    block_info(TEXTP t_ptr)
  791. {
  792.     UBYTE    str[30];
  793.     RING    t;
  794.  
  795.     block_copy(t_ptr,&t);
  796.     if (t_ptr->x1 == 0 && t_ptr->x2 == 0)
  797.         t.lines -= 1;
  798.  
  799.     make_shortpath(t_ptr->filename, str, 30);
  800.     fill_ptext(blockinfo, BLONAME, str);            /* Name mit Pfad */
  801.  
  802.     ltoa(textring_bytes(&t, t_ptr->ending), str, 10);
  803.     fill_ptext(blockinfo, BLOGROSS, str);            /* Größe in Bytes */
  804.  
  805.     ltoa((&t)->lines, str, 10);
  806.     fill_ptext(blockinfo, BLOZEILE, str);
  807.  
  808.     Arrow_mouse();
  809.     HndlDial(blockinfo, 0, FALSE, NULL, NULL);
  810.     Last_mouse();
  811.  
  812.     kill_textring(&t);
  813. }
  814.